#encoding=utf-8

import sys
reload(sys)
sys.setdefaultencoding("utf-8")  
#由于py2时代ascii时主流,因此python默认编码解码为ascii,而python在编码解码时默认转换目标是Unicode,即编码unicode→str，解码str→unicode，其中str指的是字节流，而str.decode是将字节流str按给定的解码方式解码，并转换成utf-8形式，u.encode是将unicode类按给定的编码方式转换成字节流str。注意调用encode方法的是unicode对象，生成的是字节流；调用decode方法的是str对象（字节流），生成的是unicode对象。若str对象调用encode会默认先按系统默认编码方式decode成unicode对象再encode，忽视了中间默认的decode往往导致报错


#腾讯招聘--社招  地址分析
#url = "https://hr.tencent.com/position.php?lid=2218&tid=87&keywords=python"
# #a 表示锚点 作用: 在访问时固定显示到html页面中的某个地方
#https://hr.tencent.com/position.php?keywords=c&start=30#a
#
#详情页
#https://hr.tencent.com/position_detail.php?id=45653&keywords=c&tid=0&lid=0
#
#tid--------岗位----0代表全部
#lib--------地区----0代表全部
#keywords---关键词

import requests
from bs4 import BeautifulSoup
import json

"""
json详见lagou_spider.py

json.dumps()和json.loads()是json格式处理函数,前者将python数据类型进行json格式编码(变为字符串??),后者是将json格式数据转换成字典(刚好相反)
json.dump()和json.load()主要用来读写json文件

# json.dump()函数的使用，将json信息写进文件
json_info = "{'age': '12'}"
file = open('1.json','w',encoding='utf-8')
json.dump(json_info,file)

# json.load()函数的使用，将读取json信息
file = open('1.json','r',encoding='utf-8')
info = json.load(file)
print(info)

"""

from lxml import etree


class TencentSpider(object):
    def __init__(self):
        self.headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"}
        self.base_url = "https://hr.tencent.com/position.php?start="
        self.page=0
        self.item_list = []

    def send_request(self, url):
        print('[INFO]:正在发送请求 {}'.format(url))
        response = requests.request("get", url, headers=self.headers)
        return response

    def parse_response(self, response):
        """
            注: 多页抓取的停止条件设定: 
                    1.通过提取下一页链接,并判定是否是最后一页,本代码即使这种方式
                    2.通过提取总页数,再用列表推导式方式获取所有url地址url_list = ["https://hr.tencent.com/position.php?&start=" + str(page * 10) for page in range(0, 281)],这个就可以并发处理
                        ps: 像之前访问一层层页面时,是依次添加for循环,这样干就是DFS,且迭代循环过多;而如果先将页面中链接都提取出来,再取访问,那么就是BFS了;另外,应该可以一边提取链接一边进行访问,那么就是动态的了,问题是怎么玩!!!
                    3.根据响应状态码(不是200就有问题) / 响应内容(没有需要的数据)
                        if not node_list:
                            return
            上述方式不一定都可以使用,注意选择
        """
        html = response.content
        soup = BeautifulSoup(html, 'lxml')
        #或者采用xpath
        #html_obj = etree.HTML(html)

        #提取所有tr节点的列表(每一页10个)
        tr_list = soup.find_all("tr", {"class": ["even", "odd"]})
        #tr_list = html_obj.xpath("//tr[@class='even'] | //tr[@class='odd']")
        
        for tr in tr_list:
            item = {}  #保存职位信息
            item['position_name'] = tr.find_all("td")[0].a.text  #职位名
            item['position_link'] = tr.find_all("td")[0].a.get("href")  #职位链接
            item['people_number'] = tr.find_all("td")[2].text  #招聘人数
            item['work_location'] = tr.find_all("td")[3].text  #工作地点
            item['publish_times'] = tr.find_all("td")[4].text  #发布时间
            self.item_list.append(item)

        #判断当前页是否是最后一页,如果是就return True 否则返回下一页链接
        if soup.find("a", {"class":"noactive", "id":"next"}):
        #if html_obj.xpath("//a[@class='noactive' and @id='next']")
            return True
        else:
            next_link = "https://hr.tencent.com/" + soup.find("a", {"id": "next"}).get("href")
            #next_link = "https://hr.tencent.com/" + html_obj.xpath("//a[@id='next']/@href")
            return next_link

    def save_data(self):
        #这里在转换时若有中文则需指定ensure_ascii=False,否则在序列化时对中文默认使用ascii编码(如"\u6df1\u5733"),在指定后还需指定python编码解码格式,即sys.setdefaultencoding(),否则中文还是不识别
        json_str = json.dumps(self.item_list, ensure_ascii=False)  #转为json字符串
        with open("tencent.json", "w") as f:
            f.write(json_str)
        #保存文件也可采用json,dump写入
        #json.dump(self.item_list, open("tencent.json","w"))
    

    def main(self):
        while True:
            url = self.base_url + str(self.page)
            response = self.send_request(url)
            if self.parse_response(response) == True:
                break
            self.page += 10
            self.save_data()


if __name__ == "__main__":
    tencent = TencentSpider()
    tencent.main()

